﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Mail;
using anmar.SharpMimeTools;
using Mbox2Eml.Extensions;

namespace Mbox2Eml
{
    public static class MboxUtils
    {
        public static void ProcessMessage(string outputPath, string messageIdx, string data)
        {
            string filePath = Path.Combine(outputPath, messageIdx + ".eml");

            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            using (var mailMessage = ConvertMbox2Eml(data))
            {
                mailMessage.Save(filePath);
            }
        }

        public static string[] GetMboxFiles(string mailFolder)
        {
            var files = Directory.GetFiles(mailFolder, "*.*", SearchOption.AllDirectories);

            var fileNames = new Stack<string>();
            foreach (var filename in files.Where(file => Path.GetFileName(file) == Path.GetFileNameWithoutExtension(file)).OrderBy(f => f))
            {
                var fileInfo = new FileInfo(filename);

                if (fileInfo.Length > 0)
                {
                    fileNames.Push(filename);
                }
            }

            return fileNames.OrderBy(s => s).ToArray();
        }

        public static MailMessage ConvertMbox2Eml(string data)
        {
            var sharpMsg = new SharpMessage(data);
            var mailMsg = new MailMessage();

            foreach (var mimeAddress in sharpMsg.To.Where(a => a.Length > 1))
            {
                AddRecipients(mailMsg.To, mailMsg.Headers, mimeAddress);
            }

            foreach (var mimeAddress in sharpMsg.CC.Where(a => a.Length > 1))
            {
                AddRecipients(mailMsg.CC, null, mimeAddress);
            }

            mailMsg.From = new MailAddress(sharpMsg.From.Address, sharpMsg.From.DisplayName);

            mailMsg.Subject = sharpMsg.Subject;
            mailMsg.Body = sharpMsg.Body;
            mailMsg.IsBodyHtml = sharpMsg.IsBodyHtml;

            foreach (var att in sharpMsg.Attachments)
            {
                var stream = new MemoryStream((att.Stream as MemoryStream).ToArray());
                var attachment = new Attachment(stream, att.Name, att.ContentType);

                if (!string.IsNullOrWhiteSpace(att.ContentID))
                {
                    attachment.ContentId = att.ContentID.Replace("<", string.Empty).Replace(">", string.Empty);
                }

                mailMsg.Attachments.Add(attachment);
                att.Close();
            }

            // Workaround to set the Date : Fri, 27 Jan 2012 11:37:37 +0100
            mailMsg.Headers.Add(MailMessageExtensions.X_DATE, sharpMsg.Date.ToString("ddd, d MMM yyyy HH:MM:ss K", CultureInfo.InvariantCulture));

            // Set other headers
            /*
            foreach (DictionaryEntry header in sharpMsg.Headers)
            {
                string key = (string) header.Key;
                string value = (string) header.Value;

                if (mailMsg.Headers[key] == null && !string.IsNullOrEmpty(value) && !key.StartsWith("from -"))
                {
                    mailMsg.Headers.Add(key, value.Replace("\"", string.Empty));
                }
            }
            */
            return mailMsg;
        }

        private static void AddRecipients(MailAddressCollection addresses, NameValueCollection headers, SharpMimeAddress mimeAddress)
        {
            string address = mimeAddress.Address.Replace("\"", string.Empty);
            string displayName = mimeAddress.DisplayName.Replace("\"", string.Empty);

            if (address.ToLower().Contains("undisclosed-recipient") || displayName.ToLower().Contains("undisclosed-recipient"))
            {
                addresses.Add(new MailAddress("undisclosed-recipients@mozilla.com", "undisclosed-recipients"));
                headers.Add(MailMessageExtensions.X_TO, "undisclosed-recipients");
            }
            else
            {
                addresses.Add(new MailAddress(address, displayName));
            }
        }
    }
}